// license-header java merge-point
/**
 * This is only generated once! It will never be overwritten.
 * You can (and have to!) safely modify it by hand.
 */
package edu.uwlax.cs.oayonlinestore.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

import org.springframework.dao.DataIntegrityViolationException;

import edu.uwlax.cs.oayonlinestore.entities.Category;
import edu.uwlax.cs.oayonlinestore.entities.CategoryDao;
import edu.uwlax.cs.oayonlinestore.entities.GiftCard;
import edu.uwlax.cs.oayonlinestore.entities.Order;
import edu.uwlax.cs.oayonlinestore.entities.OrderDao;
import edu.uwlax.cs.oayonlinestore.entities.OrderItem;
import edu.uwlax.cs.oayonlinestore.entities.Product;
import edu.uwlax.cs.oayonlinestore.entities.ProductLog;
import edu.uwlax.cs.oayonlinestore.entities.RetExForm;
import edu.uwlax.cs.oayonlinestore.entities.RetExFormDao;
import edu.uwlax.cs.oayonlinestore.entities.Snapshot;
import edu.uwlax.cs.oayonlinestore.entities.SnapshotDao;
import edu.uwlax.cs.oayonlinestore.entities.SnapshotItem;
import edu.uwlax.cs.oayonlinestore.entities.Subcategory;
import edu.uwlax.cs.oayonlinestore.entities.User;
import edu.uwlax.cs.oayonlinestore.entities.UserDao;
import edu.uwlax.cs.oayonlinestore.exceptions.AccessDeniedException;
import edu.uwlax.cs.oayonlinestore.exceptions.IsNotActiveException;
import edu.uwlax.cs.oayonlinestore.exceptions.UserInputException;
import edu.uwlax.cs.oayonlinestore.server.Session;
import edu.uwlax.cs.oayonlinestore.stadis.OrderStatus;
import edu.uwlax.cs.oayonlinestore.stadis.RetExStatus;
import edu.uwlax.cs.oayonlinestore.vo.CategoryStructureVO;
import edu.uwlax.cs.oayonlinestore.vo.CategoryVO;
import edu.uwlax.cs.oayonlinestore.vo.GiftCardVO;
import edu.uwlax.cs.oayonlinestore.vo.InventoryReportVO;
import edu.uwlax.cs.oayonlinestore.vo.OrderEditVO;
import edu.uwlax.cs.oayonlinestore.vo.OrderSummaryVO;
import edu.uwlax.cs.oayonlinestore.vo.ProductDetailsVO;
import edu.uwlax.cs.oayonlinestore.vo.ProductPriceVO;
import edu.uwlax.cs.oayonlinestore.vo.ProductVO;
import edu.uwlax.cs.oayonlinestore.vo.RetExFormVO;
import edu.uwlax.cs.oayonlinestore.vo.SalesReportVO;
import edu.uwlax.cs.oayonlinestore.vo.SnapshotVO;
import edu.uwlax.cs.oayonlinestore.vo.SubcategoryVO;
import edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO;
import edu.uwlax.cs.oayonlinestore.vo.UserVO;

/**
 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore
 */
public class OnlinestoreImpl extends
		edu.uwlax.cs.oayonlinestore.service.OnlinestoreBase {

	static class Attributes {
		static Attributes instance;

		static Attributes get() {
			return instance;
		}

		float shipping;

		float tax;

		public float getShipping() {
			return shipping;
		}

		public float getTax() {
			return tax;
		}

		public void setShipping(float shipping) {
			this.shipping = shipping;
		}

		public void setTax(float tax) {
			this.tax = tax;
		}

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addEditCategory(edu.uwlax.cs.oayonlinestore.vo.CategoryVO)
	 */
	protected void handleAddEditCategory(
			edu.uwlax.cs.oayonlinestore.vo.CategoryVO category)
			throws java.lang.Exception {

		// get user
		UserDetailsVO userdetails = this.handleGetLoggedInUser();
		if (userdetails.isIsAdministrator()) {

			String title = category.getTitle();
			String description = category.getDescription();

			if (title.equals("") || title == null)
				throw new UserInputException("Title is empty");
			if (description.equals("") || description == null)
				throw new UserInputException("Description is empty");

			Category cat = null;

			if (category.getId() == 0) {
				cat = getCategoryDao().categoryVOToEntity(category);
				cat.setIsActive(true);

				getCategoryDao().create(cat);
			} else {
				cat = getCategoryDao().load(category.getId());

				if (cat.isIsActive() == false)
					throw new IsNotActiveException("Category Not active");

				cat.setTitle(title);
				cat.setDescription(description);
				getCategoryDao().update(cat);

			}
		} else
			throw new AccessDeniedException();
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addEditProduct(edu.uwlax.cs.oayonlinestore.vo.ProductVO,
	 *      int)
	 */
	protected void handleAddEditProduct(
			edu.uwlax.cs.oayonlinestore.vo.ProductDetailsVO product,
			int subcategoryID) throws java.lang.Exception {

		// Subcategory sub = getSubcategoryDao().load(subcategoryID);
		UserDetailsVO u = this.handleGetLoggedInUser();
		User user = getUserDao().userDetailsVOToEntity(u);
		Collection cats = user.getManagedCategories();

		Subcategory sub = getSubcategoryDao().load(subcategoryID);
		Category cat = sub.getCategory();

		if (cats.contains(cat)) {

			if (product.getExpBackInStock().before(new Date()))
				throw new UserInputException("Invalid Date");
			if (product.getIndustrialDiscount() < 0
					|| product.getIndustrialDiscount() > 100)
				throw new UserInputException(
						"Discount must be between 0 and 100");
			if (product.getInStockCount() < 0)
				throw new UserInputException(
						"InStock Count should be greater than 0");
			if (product.getNormalDiscount() < 0
					|| product.getNormalDiscount() > 100)
				throw new UserInputException(
						"Discount must be between 0 and 100");
			if (product.getIndustrialDiscount() < 0
					|| product.getIndustrialDiscount() > 100)
				throw new UserInputException(
						"Discount must be between 0 and 100");
			if (product.getPrice() < 0)
				throw new UserInputException("Price must be greater than 0");

			//getProductDao.findByBrandAndName(product.getName(),product.getBrand());
			
			
			
			Product pro = null;

			if (product.getId() == 0) {

				// pro = getProductDao().productDetailsVOToEntity(product);
				pro = getProductDao().create(product.getBrand(),
						product.getDescription(), product.getExpBackInStock(),
						product.getIndustrialDiscount(),
						product.getInStockCount(), true, product.getName(),
						product.getNormalDiscount(), product.getPrice(),
						product.getSize(), sub);

				getProductLogDao().create(new Date(), pro,
						product.getInStockCount());

			} else {

				pro = getProductDao().load(product.getId());
				if (pro.isIsActive() == false)
					throw new IsNotActiveException("Product is inActive");
				else {
					int oldInStock = pro.getInStockCount();
					pro.setBrand(product.getBrand());
					pro.setDescription(product.getDescription());
					pro.setExpBackInStock(product.getExpBackInStock());
					pro.setIndustrialDiscount(product.getIndustrialDiscount());
					pro.setInStockCount(product.getInStockCount());
					pro.setName(product.getName());
					pro.setNormalDiscount(product.getNormalDiscount());
					pro.setPrice(product.getPrice());
					pro.setSize(product.getSize());

					getProductDao().update(pro);
					getProductLogDao().create(new Date(), pro,
							product.getInStockCount() - oldInStock);

				}
			}

		} else
			throw new AccessDeniedException();

		// /////////////////////////////////////
	}

	protected void handleAddEditRetExForm(RetExFormVO retExForm, int orderItemID)
			throws Exception {

		AccessControl.forceCanEditRetExForms();

		String qerr = "The quantity can not be more than the quantity of products that has been ordered.";

		if (retExForm.getQuantity() < 1)
			throw new UserInputException("Quantity must be one or more.");

		if (orderItemID != 0) {
			OrderItem oi = getOrderItemDao().load(orderItemID);
			if (oi == null)
				throw new UserInputException("Invalid orderItemID");
			if (retExForm.getQuantity() > oi.getQuantity())
				throw new UserInputException(qerr);
			getRetExFormDao().create(new Date(), retExForm.getDescription(),
					oi, retExForm.getQuantity(),
					RetExStatus.fromString(retExForm.getStatus()),
					oi.getOrder().getUser());
		} else {
			int maxquant = getRetExFormDao().load(retExForm.getId())
					.getOrderItem().getQuantity();
			if (retExForm.getQuantity() > maxquant)
				throw new UserInputException(qerr);
			RetExForm form = getRetExFormDao().retExFormVOToEntity(retExForm);
			getRetExFormDao().update(form);
		}
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addEditSubcategory(edu.uwlax.cs.oayonlinestore.vo.SubcategoryVO,
	 *      int)
	 */
	protected void handleAddEditSubcategory(
			edu.uwlax.cs.oayonlinestore.vo.SubcategoryVO subcategory,
			int categoryID) throws java.lang.Exception {

		User user = getUserDao().userDetailsVOToEntity(
				this.handleGetLoggedInUser());

		Category cat = getCategoryDao().load(categoryID);
		Iterator i = user.getManagedCategories().iterator();
		boolean flag = false;
		while (i.hasNext() && !flag) {
			Category c = (Category) i.next();
			if (cat != null)
				if (c.getId() == cat.getId())
					flag = true;
		}
		if (!flag)
			throw new AccessDeniedException();
		else {

			Subcategory sub = null;
			if (subcategory.getId() == 0) {

				// sub = getSubcategoryDao().subcategoryVOToEntity(subcategory);
				// if(sub != null)
				getSubcategoryDao().create(cat, subcategory.getDescription(),
						true, subcategory.getTitle());

			} else {

				sub = getSubcategoryDao().load(subcategory.getId());

				if (sub.isIsActive() == false)
					throw new IsNotActiveException("Subcategory does not exist");
				else {

					sub.setDescription(subcategory.getDescription());
					sub.setTitle(subcategory.getTitle());

					getSubcategoryDao().update(sub);

				}

			}
			// getSubcategoryDao().load(subcategory.getId());

		}

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addEditUser(edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO)
	 */
	protected void handleAddEditUser(
			edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO user)
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator()) {

			user.setIsSalesManager(false);
			user.setIsAdministrator(false);
			user.setIsSalesStaff(false);
			user.setCanBeCategoryPerson(false);
		}

		if (user.getLogin().length() < 3 || user.getLogin().length() > 32)
			throw new UserInputException("Invalid LogIn name");
		if (user.getPassword().length() < 3 || user.getPassword().length() > 32)
			throw new UserInputException("Invalid password");
		if (!user.getEmail().contains("@"))
			throw new UserInputException("Invalid email address");
		if (user.getZipcode() < 0)
			throw new UserInputException("Invalid Zip Code");
		if (String.valueOf(user.getZipcode()).length() != 5)
			throw new UserInputException("Invalid Zip Code");

		// check CCExpiration date only if ccnumber has been set.
		if ((user.getCcNumber() != null) && (user.getCcNumber().length() > 0))
			if (((user.getCcExpirationDate() != null) && user
					.getCcExpirationDate().before(new Date())))
				throw new UserInputException(
						"Invalid Credit Card Expiration Date");

		// a user can be either a normal or an industrial customer
		if (user.isIsIndustrialCustomer())
			user.setIsNormalCustomer(false);

		try {
			User newUser = getUserDao().userDetailsVOToEntity(user);

			if (user.getId() == 0) {
				if (user.isIsIndustrialCustomer())
					newUser.setIsActive(false);

				getUserDao().create(newUser);
			} else {
				if (!this.handleGetLoggedInUser().isIsAdministrator()
						&& user.getId() != this.handleGetLoggedInUser().getId())
					throw new AccessDeniedException();

				getUserDao().update(newUser);

				if (user.getId() == Session.get().getUser().getId())
					Session.get().setUser(user);
			}
		} catch (DataIntegrityViolationException e) {
			throw new UserInputException("The login name already exists.", e);
		}
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addGiftCardToOrder(int,
	 *      java.lang.String)
	 */
	protected void handleAddGiftCardToOrder(int orderID, java.lang.String cardID)
			throws java.lang.Exception {

		Order order = getOrderDao().load(orderID);
		GiftCard gc = getGiftCardDao().findByCardID(cardID);

		AccessControl.forceCanEditOrder(order);

		if (gc == null)
			throw new UserInputException("The gift card ID is invalid.");
		if (gc.getOrder() != null)
			throw new UserInputException("The gift card is already in use.");

		gc.setOrder(order);
		getGiftCardDao().update(gc);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addManagerToCategory(int,
	 *      int)
	 */
	protected void handleAddManagerToCategory(int categoryID, int userID)
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		User user = getUserDao().load(userID);
		Category cat = getCategoryDao().load(categoryID);
		if (user.isIsActive()) {
			cat.addManager(user);
			getCategoryDao().update(cat);
		}

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addProductToOrder(int,
	 *      int, int)
	 */
	protected void handleAddProductToOrder(int productID, int amount,
			int orderID) throws java.lang.Exception {

		if (amount < 1)
			throw new UserInputException("Invalid amount");

		Product p = getProductDao().load(productID);
		Order o = null;
		UserDetailsVO user = Session.get().getUser();

		if (orderID == 0) {
			AccessControl.forceCanCreateOrder();
			o = getOrderDao().create(user.getCity(), user.getState(),
					user.getStreetAddr(), user.getZipcode(), null,
					user.getCity(), user.getState(), user.getStreetAddr(),
					user.getZipcode(), OrderStatus.IN_PROGRESS,
					getUserDao().load(user.getId()));
			o.setCcCompany(user.getCcCompany());
			o.setCcExpirationDate(user.getCcExpirationDate());
			o.setCcNumber(user.getCcNumber());
		} else {
			o = getOrderDao().load(orderID);
			AccessControl.forceCanEditOrder(o);
		}

		float discount;
		if (user.isIsIndustrialCustomer())
			discount = p.getIndustrialDiscount();
		else
			discount = p.getNormalDiscount();

		getOrderItemDao().create(discount, o, p.getPrice(), p, amount);

		Session.get().setOrderID(o.getId());
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#addStaffToCategory(int,
	 *      int)
	 */
	protected void handleAddStaffToCategory(int categoryID, int userID)
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		User user = getUserDao().load(userID);
		Category cat = getCategoryDao().load(categoryID);
		if (user.isIsActive()) {
			cat.addStaff(user);
			getCategoryDao().update(cat);
		}

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#approveIndustrialUser(int)
	 */
	protected void handleApproveIndustrialUser(int userID)
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		User user = getUserDao().load(userID);
		user.approveIndustrialUser();
		getUserDao().update(user);

	}

	protected void handleCreateSnapshot() throws Exception {
		AccessControl.forceCanAccessInventoryReports();
		Snapshot snapshot = getSnapshotDao().create(new Date());
		for (Iterator i = getProductDao().loadAll().iterator(); i.hasNext();) {
			Product p = (Product) i.next();
			getSnapshotItemDao().create(p.getInStockCount(), p, snapshot);
		}
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#deleteGiftCard(int)
	 */
	protected void handleDeleteGiftCard(int giftCardID)
			throws java.lang.Exception {

		// /////////////////////////////////////////////
		// MAY NEED REVISION !!
		// ////////////////////////////////////////////
		if (!this.handleGetLoggedInUser().isIsSalesManager())
			throw new AccessDeniedException();

		GiftCard gc = getGiftCardDao().load(giftCardID);
		getGiftCardDao().remove(gc);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#deleteOrderItem(int)
	 */
	protected void handleDeleteOrderItem(int orderItemID)
			throws java.lang.Exception {

		OrderItem ot = getOrderItemDao().load(orderItemID);

		AccessControl.forceCanEditOrder(ot.getOrder());

		getOrderItemDao().remove(ot);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#disableCategory(int)
	 */
	protected void handleDisableCategory(int categoryID)
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		Category cat = getCategoryDao().load(categoryID);
		cat.setIsActive(false);
		getCategoryDao().update(cat);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#disableProduct(int)
	 */
	protected void handleDisableProduct(int productID)
			throws java.lang.Exception {

		Product p = getProductDao().load(productID);
		Subcategory sub = p.getSubcategory();
		Category cat = sub.getCategory();

		User user = getUserDao().userDetailsVOToEntity(
				this.handleGetLoggedInUser());

		if (!cat.getManagers().contains(user))
			throw new AccessDeniedException();

		p.setIsActive(false);
		getProductDao().update(p);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#disableSubcategory(int)
	 */
	protected void handleDisableSubcategory(int subcategoryID)
			throws java.lang.Exception {

		Subcategory sub = getSubcategoryDao().load(subcategoryID);
		Category cat = sub.getCategory();
		User user = getUserDao().userDetailsVOToEntity(
				this.handleGetLoggedInUser());

		if (!cat.getManagers().contains(user))
			throw new AccessDeniedException();

		sub.setIsActive(false);
		getSubcategoryDao().update(sub);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#generateGiftCards(int,
	 *      int)
	 */
	protected void handleGenerateGiftCards(int count, int moneyValue)
			throws java.lang.Exception {

		if (count < 1)
			throw new UserInputException("invalid quantity.");
		if (moneyValue < 1)
			throw new UserInputException("invalid money value.");

		if (!this.handleGetLoggedInUser().isIsSalesManager())
			throw new AccessDeniedException();

		for (int i = 0; i < count; i++) {
			GiftCard gc = getGiftCardDao().create(moneyValue, "");
			String cardID = gc.generateCardID();
			gc.setCardID(cardID);
			getGiftCardDao().update(gc);
		}
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#generateTestData()
	 */
	protected void handleGenerateTestData() throws java.lang.Exception {

		/** ************ Generate some common TestData ************ */

		// create some categories
		Category cHardware = getCategoryDao().create(true, "Hardware",
				"Modders' paradies");
		Category cSoftware = getCategoryDao().create(true, "Software",
				"Orace, SAP, Microsoft, Adobe, we have it all!");
		Category cMovies = getCategoryDao().create(true, "Movies",
				"Let us entertain you!");

		// create some users with varying rights

		// for (int i = 0; i < 256; i++) {
		// getUserDao()
		// .create((i & 2) != 0, "user" + i, "pwd" + i,
		// "firstname" + i, "lastname" + i,
		// "email" + i + "@gmail.com", "streetAddr" + i,
		// "city" + i, "state" + i, 10000 + i,
		// "teleNumber" + i, "ccNumber" + i, "ccCompany" + i,
		// new Date(), (i & 4) != 0, (i & 8) != 0,
		// (i & 16) != 0, (i & 32) != 0, (i & 64) != 0,
		// (i & 128) != 0);
		//
		// /*
		// * if(i%2 == 0){ cHardware.addManager(u);
		// * getCategoryDao().update(cHardware); } else{
		// * cSoftware.addManager(u); getCategoryDao().update(cSoftware); }
		// */
		//
		// }

		// cHardware.addManager(manager)

		// create some subcategories
		Subcategory Cases = getSubcategoryDao().create(cHardware,
				"In every Size", true, "Cases");
		Subcategory CPUs = getSubcategoryDao().create(cHardware,
				"Numbercrunchers!", true, "CPUs");
		Subcategory Harddrives = getSubcategoryDao().create(cHardware,
				"Terrabytes!", true, "Harddrives");
		Subcategory Laptops = getSubcategoryDao().create(cHardware,
				"HP, Dell, Apple...", true, "Laptops");
		Subcategory Memory = getSubcategoryDao().create(cHardware,
				"Gigabytes!", true, "Memory");

		Subcategory Office = getSubcategoryDao().create(cSoftware, "", true,
				"Office");
		Subcategory OS = getSubcategoryDao().create(cSoftware, "", true, "OS");
		Subcategory Drawing = getSubcategoryDao().create(cSoftware, "", true,
				"Drawing");
		Subcategory ERP = getSubcategoryDao()
				.create(cSoftware, "", true, "ERP");

		Subcategory Horror = getSubcategoryDao().create(cMovies, "", true,
				"Horror");
		Subcategory Sci_Fi = getSubcategoryDao().create(cMovies, "", true,
				"Sci-Fi");
		Subcategory Love = getSubcategoryDao()
				.create(cMovies, "", true, "Love");
		Subcategory Family = getSubcategoryDao().create(cMovies, "", true,
				"Family");
		Subcategory Comedy = getSubcategoryDao().create(cMovies, "", true,
				"Comedy");

		getProductDao()
				.create(
						"Sony",
						"Very nice case. Includes Electronic cpu status tracker...",
						new Date(), 10, 50, true, "Sony Case", 5, 45,
						"30x50x70", Cases);
		getProductDao().create("Panasonic", "Very nice case.", new Date(), 12,
				60, true, "Panasonic Case", 7, 50, "30x30x70", Cases);
		getProductDao().create("Intel", "Dual 2 Core, 8MB cache", new Date(),
				4, 30, true, "Intel Dual Core CPU", 5, 45, "2x2", CPUs);
		getProductDao().create("AMD", "Fast processor", new Date(), 10, 50,
				true, "AMD 64bit CPU", 5, 45, "30x50x70", CPUs);
		getProductDao().create("Seagate", "Large Capacity. 400 GB", new Date(),
				10, 50, true, "Seagate 400GB", 5, 45, "30x10x20", Harddrives);

		getProductDao().create("Western Digital",
				"600GB space. Store up to 100000 songs.", new Date(), 10, 50,
				true, "WD 600GB", 5, 45, "30x50x70", Harddrives);
		getProductDao().create("Sony", "FE 770 G", new Date(), 10, 50, true,
				"Sony FE series", 5, 45, "30x50x70", Laptops);
		getProductDao().create("HP", "Glossy material, with nice keyboard",
				new Date(), 10, 50, true, "HP Pavilion", 5, 45, "30x50x70",
				Laptops);

		getProductDao().create("Dell", "1 GB memory. DDRAM", new Date(), 10,
				50, true, "Dell DDRAM", 5, 45, "30x50x70", Memory);

		getProductDao().create("BallPoint", "0.5 Fine Pen", new Date(), 10, 50,
				true, "BallPoint Pen", 5, 45, "30x50x70", Office);

		for (int i = 4; i < 30; i++) {
			GiftCard g = getGiftCardDao().create(((i * 3) / 10) * 10, "");
			g.setCardID(g.generateCardID());
		}

		User Moritz = getUserDao().create(true, "Moritz", "m", "Moritz",
				"Eysholdt", "Moritz@Eysholdt.de", "16th Street", "La Crosse",
				"WI", 123456, "608 789 2025", "", "", new Date(), true, true,
				true, true, false, true);
		cHardware.addManager(Moritz);
		cSoftware.addStaff(Moritz);

		/** ********************* Create Test Data for Test Cases ************* */

		User adm = getUserDao().create(true, "QAY", "Qay&1*5 ", "QAY ", "YAQ",
				"qay@yahoo.com", " ", "", " ", 12345, " ", "", "", new Date(),
				true, false, false, false, false, false);
		User c = getUserDao().create(true, "Cust1", " ", " ", "", "", " ", "",
				" ", 12345, " ", "", "", new Date(), false, false, false,
				false, true, false);
		User m1 = getUserDao().create(true, "Manager1", "Manage&5/5", "Said",
				"XYZ", "manager@yahoo.com", "", "", "", 45677, "", "", "",
				new Date(), false, true, false, false, false, true);
		User m2 = getUserDao().create(true, "Manager2", "Manage", "SaidAbc",
				"XYZ", "manager1@yahoo.com", "", "", "", 45677, "", "", "",
				new Date(), false, true, false, false, false, true);
		User c2 = getUserDao().create(true, "cust1", " ", "Peter", "Pan", "",
				" ", "", " ", 12345, " ", "", "", new Date(), false, false,
				false, true, false, true);
		User c3 = getUserDao().create(true, "Admin", " ", "Sidney", "Paris",
				"", " ", "", " ", 34567, " ", "", "", new Date(), false, false,
				false, false, true, false);

		Category TV = getCategoryDao().create(true, "Televisions",
				"All kinds of TV!!");

		TV.addManager(Moritz);
		User staff1 = getUserDao().create(true, "AABB", "staff", "  ", "  ",
				"staff1@yahoo.com", "", "", "", 49077, "", "", "", new Date(),
				false, false, true, true, false, true);
		TV.addStaff(staff1);
		Category clothes = getCategoryDao().create(true, "clothes",
				"All kinds of clothes!!");
		cSoftware.addManager(m1);

		getSubcategoryDao().create(TV, "All Laptop", true, "Laptop");

		java.sql.Date exdate = java.sql.Date.valueOf("01-01-01");
		Product prod = getProductDao().create("IBM", "15.4", exdate, 0.12f, 50,
				true, "T61", 0.12f, 12.99f, "medum", CPUs);
		Product prod1 = getProductDao().create("IBM", "15.4", exdate, 0.10f,
				100, true, "T61", 0.12f, 1234f, "medum", CPUs);
		Product prod2 = getProductDao().create("IBM", "15.4", exdate, 0.00f, 1,
				true, "T61", 0.12f, 1234f, "medum", CPUs);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getApprovableIndustrialUsers()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserVO[] handleGetApprovableIndustrialUsers()
			throws java.lang.Exception {
		;

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		Collection c = getUserDao().loadAll();
		ArrayList Industrialusers = new ArrayList();

		for (Iterator i = c.iterator(); i.hasNext();) {
			User u = (User) i.next();
			if (!u.isIsActive() && u.isIsIndustrialCustomer())
				Industrialusers.add(getUserDao().toUserVO(u));

		}
		return (UserVO[]) Industrialusers.toArray(new UserVO[Industrialusers
				.size()]);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getCategory(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.CategoryVO handleGetCategory(
			int categoryID) throws java.lang.Exception {

		Category cat = getCategoryDao().load(categoryID);
		if (!cat.isIsActive())
			throw new UserInputException("Category does not exist");

		return getCategoryDao().toCategoryVO(cat);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getCategoryList()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.CategoryVO[] handleGetCategoryList()
			throws java.lang.Exception {

		Collection c = getCategoryDao().loadAll();
		ArrayList activecats = new ArrayList();

		for (Iterator i = c.iterator(); i.hasNext();) {
			Category cat = (Category) i.next();
			if (cat.isIsActive())
				activecats.add(getCategoryDao().toCategoryVO(cat));

		}
		return (CategoryVO[]) activecats.toArray(new CategoryVO[activecats
				.size()]);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getCategoryManagerList(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserVO[] handleGetCategoryManagerList(
			int categoryID) throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		Category cat = getCategoryDao().load(categoryID);
		// Vector mans = new Vector(cat.getManagers());
		Collection c = cat.getManagers();
		ArrayList managers = new ArrayList();

		for (Iterator i = c.iterator(); i.hasNext();) {
			User user = (User) i.next();
			if (user.isIsActive())
				managers.add(getUserDao().toUserVO(user));
		}
		return (UserVO[]) managers.toArray(new UserVO[managers.size()]);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getCategoryPeopleList()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserVO[] handleGetCategoryPeopleList()
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		Collection allusers = getUserDao().loadAll();
		// Vector catpeople = new Vector();
		ArrayList people = new ArrayList();

		for (Iterator i = allusers.iterator(); i.hasNext();) {
			User u = (User) i.next();
			if (u.isCanBeCategoryPerson() && u.isIsActive())
				people.add(getUserDao().toUserVO(u));
		}

		return (UserVO[]) people.toArray(new UserVO[people.size()]);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getCategoryStaffList(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserVO[] handleGetCategoryStaffList(
			int categoryID) throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		Category cat = getCategoryDao().load(categoryID);
		Collection c = cat.getStaffMembers();
		ArrayList staff = new ArrayList();

		for (Iterator i = c.iterator(); i.hasNext();) {
			User user = (User) i.next();
			if (user.isIsActive())
				staff.add(getUserDao().toUserVO(user));
		}

		return (UserVO[]) staff.toArray(new UserVO[staff.size()]);
		;
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getCategoryStructureList()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.CategoryStructureVO[] handleGetCategoryStructureList()
			throws java.lang.Exception {
		Collection cats = getCategoryDao().findActive(
				CategoryDao.TRANSFORM_CATEGORYSTRUCTUREVO, true);
		return (CategoryStructureVO[]) cats
				.toArray(new CategoryStructureVO[cats.size()]);
	}

	protected OrderSummaryVO handleGetCurrentOrder() throws Exception {
		int id = Session.get().getOrderID();
		if (id == 0)
			return new OrderSummaryVO(0, new Date(), null, 0.0f, 0.0f, 0.0f,
					0.0f, Session.get().getUser(), 0, "");
		return (OrderSummaryVO) getOrderDao().load(
				OrderDao.TRANSFORM_ORDERSUMMARYVO, id);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getEditableCategoriesForCurrentUser()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.CategoryVO[] handleGetEditableCategoriesForCurrentUser()
			throws java.lang.Exception {

		User user = getUserDao().userDetailsVOToEntity(
				this.handleGetLoggedInUser());
		// Vector all = new Vector();
		Collection staffCats = user.getStaffInCategories();
		Collection manCats = user.getManagedCategories();
		ArrayList all = new ArrayList();

		for (Iterator i = staffCats.iterator(); i.hasNext();) {
			Category cat = (Category) i.next();
			if (cat.isIsActive())
				all.add(getCategoryDao().toCategoryVO(cat));
		}
		for (Iterator i = manCats.iterator(); i.hasNext();) {
			Category cat = (Category) i.next();
			if (cat.isIsActive()) {
				int k = 0;
				boolean flag = false;
				while (!flag && k < all.size()) {
					if (((CategoryVO) all.get(k)).getId() == cat.getId())
						flag = true;
					k++;
				}
				if (!flag)
					all.add(getCategoryDao().toCategoryVO(cat));
			}
		}

		return (CategoryVO[]) all.toArray(new CategoryVO[all.size()]);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getGiftCardList()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.GiftCardVO[] handleGetGiftCardList()
			throws java.lang.Exception {

		Collection c = getGiftCardDao().loadAll();
		ArrayList availableGC = new ArrayList();

		for (Iterator i = c.iterator(); i.hasNext();) {

			GiftCard gc = (GiftCard) i.next();
			if (gc.getOrder() == null)
				availableGC.add(getGiftCardDao().toGiftCardVO(gc));

		}

		return (GiftCardVO[]) availableGC.toArray(new GiftCardVO[availableGC
				.size()]);
	}

	protected InventoryReportVO[] handleGetInventoryReport(int snapshot1ID,
			int snapshot2ID) throws Exception {
		AccessControl.forceCanAccessInventoryReports();

		HashMap map = new HashMap() {
			private static final long serialVersionUID = 4125865565458487172L;

			public Object get(Object key) {
				ProductVO p = (ProductVO) key;
				Integer k = new Integer(p.getId());
				Object o = super.get(k);
				if (o == null)
					put(k, o = new InventoryReportVO(p, 0, 0, 0, 0, 0));
				return o;
			}
		};

		Snapshot sn1 = getSnapshotDao().load(snapshot1ID);
		if (sn1 == null)
			throw new UserInputException("Invalid snapshotID");
		Snapshot sn2 = getSnapshotDao().load(snapshot2ID);
		if (sn2 == null)
			throw new UserInputException("Invalid snapshotID");
		if (sn1.getId() == sn2.getId())
			throw new UserInputException("The snapshots must differ");
		if (sn1.getDate().getTime() > sn2.getDate().getTime()) {
			Snapshot t = sn1;
			sn1 = sn2;
			sn2 = t;
		}

		// set opening value
		for (Iterator i = sn1.getSnapshotItems().iterator(); i.hasNext();) {
			SnapshotItem si = (SnapshotItem) i.next();
			ProductVO p = getProductDao().toProductVO(si.getProduct());
			InventoryReportVO rep = (InventoryReportVO) map.get(p);
			rep.setOpening(si.getInStockCount());
		}

		// set closing value
		for (Iterator i = sn2.getSnapshotItems().iterator(); i.hasNext();) {
			SnapshotItem si = (SnapshotItem) i.next();
			ProductVO p = getProductDao().toProductVO(si.getProduct());
			InventoryReportVO rep = (InventoryReportVO) map.get(p);
			rep.setClosing(si.getInStockCount());
		}

		// sum up the quantity of sold items
		Collection orders = getOrderDao().findByTimespan(sn1.getDate(),
				sn2.getDate());
		for (Iterator i = orders.iterator(); i.hasNext();)
			for (Iterator j = ((Order) i.next()).getItems().iterator(); j
					.hasNext();) {
				OrderItem oi = (OrderItem) j.next();
				ProductVO p = getProductDao().toProductVO(oi.getProduct());
				InventoryReportVO rep = (InventoryReportVO) map.get(p);
				rep.setSold(rep.getSold() + oi.getQuantity());

			}
		// get returned items

		// sum up the quantity of returned items
		Collection retex = getRetExFormDao().findByTimespan(sn1.getDate(),
				sn2.getDate());
		for (Iterator i = retex.iterator(); i.hasNext();) {
			RetExForm ret = (RetExForm) i.next();
			ProductVO p = getProductDao().toProductVO(
					ret.getOrderItem().getProduct());
			InventoryReportVO rep = (InventoryReportVO) map.get(p);
			rep.setReturned(rep.getReturned() + ret.getQuantity());
		}

		// sum up the quantity of added items
		Collection log = getProductLogDao().findByTimespan(sn1.getDate(),
				sn2.getDate());
		for (Iterator i = log.iterator(); i.hasNext();) {
			ProductLog ret = (ProductLog) i.next();
			ProductVO p = getProductDao().toProductVO(ret.getProduct());
			InventoryReportVO rep = (InventoryReportVO) map.get(p);
			rep.setAdded(rep.getAdded() + ret.getQuantityAdded());
		}

		Collection r = map.values();

		return (InventoryReportVO[]) r.toArray(new InventoryReportVO[r.size()]);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getLoggedInUser()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO handleGetLoggedInUser()
			throws java.lang.Exception {
		return Session.get().getUser();
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getOrderEdit(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.OrderEditVO handleGetOrderEdit(
			int orderID) throws java.lang.Exception {

		Order o = getOrderDao().load(orderID);
		if (o == null)
			throw new UserInputException("Invalid orderID.");
		AccessControl.forceCanReadOrder(o);
		return getOrderDao().toOrderEditVO(o);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getOrderExtended(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.OrderExtendedVO handleGetOrderExtended(
			int orderID) throws java.lang.Exception {

		Order o = getOrderDao().load(orderID);
		if (o == null)
			throw new UserInputException("Order not found.");
		AccessControl.forceCanReadOrder(o);

		return getOrderDao().toOrderExtendedVO(o);
	}

	protected OrderSummaryVO[] handleGetOrdersByLastNameAndZip(String lastname,
			int zip) throws Exception {

		Collection c = getUserDao().findByLastNameAndZip(lastname, zip);
		ArrayList orders = new ArrayList();
		for (Iterator i = c.iterator(); i.hasNext();) {

			User u = (User) i.next();
			if (u.isIsActive()) {
				Collection o = u.getOrders();
				getOrderDao().toOrderSummaryVOCollection(o);
				orders.addAll(o);
			} else
				throw new RuntimeException("Invalid user information");

		}
		return (OrderSummaryVO[]) orders.toArray(new OrderSummaryVO[orders
				.size()]);

	}

	protected OrderSummaryVO[] handleGetOrderSummaryList(int userID)
			throws Exception {
		Collection orders;
		if (userID == 0) {
			AccessControl.forceCanAdminOrders();
			orders = getOrderDao().loadAll(OrderDao.TRANSFORM_ORDERSUMMARYVO);
		} else {
			User u = getUserDao().load(userID);
			AccessControl.forceBrowseOwnOrders(u.getId());
			orders = getOrderDao().findOrdersByUser(
					OrderDao.TRANSFORM_ORDERSUMMARYVO, u);
		}
		return (OrderSummaryVO[]) orders.toArray(new OrderSummaryVO[orders
				.size()]);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getProductDetailList(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.ProductDetailsVO[] handleGetProductDetailList(
			int subcategoryID) throws java.lang.Exception {

		Subcategory sub = getSubcategoryDao().load(subcategoryID);

		ArrayList prods = new ArrayList();
		for (Iterator i = sub.getProducts().iterator(); i.hasNext();) {
			Product p = (Product) i.next();
			if (p.isIsActive())
				prods.add(getProductDao().toProductDetailsVO(p));
		}
		return (ProductDetailsVO[]) prods.toArray(new ProductDetailsVO[prods
				.size()]);

	}

	protected RetExFormVO handleGetRetExForm(int formID) throws Exception {
		AccessControl.forceCanEditRetExForms();
		RetExFormVO r = (RetExFormVO) getRetExFormDao().load(
				RetExFormDao.TRANSFORM_RETEXFORMVO, formID);
		if (r == null)
			throw new UserInputException("Invalid RetExFormID");
		return r;
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getRetExFormsList()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.RetExFormVO[] handleGetRetExFormsList()
			throws java.lang.Exception {
		AccessControl.forceCanEditRetExForms();
		Collection c = getRetExFormDao().loadAll(
				RetExFormDao.TRANSFORM_RETEXFORMVO);
		return (RetExFormVO[]) c.toArray(new RetExFormVO[c.size()]);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getSalesReport(java.util.Date)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.SalesReportVO handleGetSalesReport(
			java.util.Date date) throws java.lang.Exception {
		AccessControl.forceCanViewSalesReport();
		final int DAY = 1000 * 60 * 60 * 24;
		Date d2 = new Date(date.getTime() + DAY);
		ArrayList oi = new ArrayList();
		for (Iterator i = getOrderDao().findByTimespan(date, d2).iterator(); i
				.hasNext();) {
			Collection l = ((Order) i.next()).getItems();
			getOrderItemDao().toOrderItemVOCollection(l);
			oi.addAll(l);
		}
		SalesReportVO r = SalesReport.generateSalesReport(oi);
		r.setFromDate(date);
		r.setToDate(d2);
		return r;
	}

	protected SnapshotVO[] handleGetSnapshotList() throws Exception {
		AccessControl.forceCanAccessInventoryReports();
		Collection sn = getSnapshotDao().loadAll(
				SnapshotDao.TRANSFORM_SNAPSHOTVO);
		return (SnapshotVO[]) sn.toArray(new SnapshotVO[sn.size()]);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getSubcategories(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.SubcategoryVO[] handleGetSubcategories(
			int categoryID) throws java.lang.Exception {

		Category cat = getCategoryDao().load(categoryID);
		if (!cat.isIsActive())
			throw new IsNotActiveException("Category does not exist");

		Collection c = cat.getSubcategories();
		ArrayList activesubs = new ArrayList();

		for (Iterator i = c.iterator(); i.hasNext();) {
			Subcategory sub = (Subcategory) i.next();
			if (sub.isIsActive())
				activesubs.add(getSubcategoryDao().toSubcategoryVO(sub));

		}
		return (SubcategoryVO[]) activesubs
				.toArray(new SubcategoryVO[activesubs.size()]);

	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getUserDetail(int)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO handleGetUserDetail(
			int userID) throws java.lang.Exception {

		UserDetailsVO curr = Session.get().getUser();
		if (!curr.isIsSalesManager() && !curr.isIsSalesStaff()
				&& !curr.isIsAdministrator() && userID != curr.getId())
			throw new AccessDeniedException();

		User user = getUserDao().load(userID);
		if ((user == null) || !user.isIsActive())
			throw new IsNotActiveException("User does not exist");

		UserDetailsVO uv = getUserDao().toUserDetailsVO(user);

		return uv;
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#getUserDetailList()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO[] handleGetUserDetailList()
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();
		Collection c = getUserDao().loadAll(UserDao.TRANSFORM_USERDETAILSVO);
		ArrayList activeusers = new ArrayList();

		for (Iterator i = c.iterator(); i.hasNext();) {
			UserDetailsVO uvo = (UserDetailsVO) i.next();
			if (uvo.isIsActive())
				activeusers.add(uvo);

		}
		return (UserDetailsVO[]) activeusers
				.toArray(new UserDetailsVO[activeusers.size()]);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#login(java.lang.String,
	 *      java.lang.String)
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO handleLogin(
			java.lang.String login, java.lang.String pwd)
			throws java.lang.Exception {
		UserDetailsVO u = (UserDetailsVO) getUserDao().findByLogin(
				UserDao.TRANSFORM_USERDETAILSVO, login);

		if ((u == null) || !u.getPassword().equals(pwd))
			throw new UserInputException("Login incorrect");

		if (!u.isIsActive())
			throw new UserInputException("User is not active");
		Session.get().setUser(u);
		return u;
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#logout()
	 */
	protected edu.uwlax.cs.oayonlinestore.vo.UserDetailsVO handleLogout()
			throws java.lang.Exception {
		Session s = Session.get();
		s.resetUser();
		s.setOrderID(0);
		return s.getUser();
	}

	protected void handlePlaceOrder(int orderID) throws Exception {

		Order order = getOrderDao().load(orderID);
		AccessControl.forceCanEditOrder(order);

		boolean waiting = false;
		for (Iterator i = order.getItems().iterator(); i.hasNext();) {
			OrderItem ort = (OrderItem) i.next();
			Product p = ort.getProduct();
			p.setInStockCount(p.getInStockCount() - ort.getQuantity());
			if (p.getInStockCount() < 0)
				waiting = true;
			getProductDao().update(p);
		}
		order.setStatus((waiting) ? OrderStatus.WAITING_FOR_ITEMS
				: OrderStatus.SUBMITTED);
		order.setOrderDate(new Date());
		getOrderDao().update(order);

		Session.get().setOrderID(0);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#removeGiftCardFromOrder(int,
	 *      int)
	 */
	protected void handleRemoveGiftCardFromOrder(int orderID, int giftCardID)
			throws java.lang.Exception {

		Order order = getOrderDao().load(orderID);
		GiftCard gc = getGiftCardDao().load(giftCardID);

		AccessControl.forceCanEditOrder(order);

		if (gc.getOrder().getId() == order.getId()) {
			gc.setOrder(null);
			getGiftCardDao().update(gc);
		} else
			throw new UserInputException(
					"The gift card does not belog to the specified order.");
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#removeManagerFromCategory(int,
	 *      int)
	 */
	protected void handleRemoveManagerFromCategory(int categoryID, int userID)
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		Category c = getCategoryDao().load(categoryID);
		User u = getUserDao().load(userID);

		if (u.getManagedCategories().contains(c)) {

			c.removeManager(u);
			getCategoryDao().update(c);
		}
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#removeStaffFromCategory(int,
	 *      int)
	 */
	protected void handleRemoveStaffFromCategory(int categoryID, int userID)
			throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		Category c = getCategoryDao().load(categoryID);
		User u = getUserDao().load(userID);

		if (u.getStaffInCategories().contains(c)) {

			c.removeStaff(u);
			getCategoryDao().update(c);
		}
	}

	protected void handleSetCurrentOrder(int orderID) throws Exception {
		Order o = getOrderDao().load(orderID);
		if (o == null)
			throw new UserInputException("Invalid orderID.");
		AccessControl.forceCanEditOrder(o);
		Session.get().setOrderID(o.getId());
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#setOrderItemAmount(int,
	 *      int)
	 */
	protected void handleSetOrderItemAmount(int orderItemID, int ammount)
			throws java.lang.Exception {

		if (ammount < 1)
			throw new UserInputException("Invalid Ammount");

		OrderItem or = getOrderItemDao().load(orderItemID);

		AccessControl.forceCanEditOrder(or.getOrder());

		or.setQuantity(ammount);
		getOrderItemDao().update(or);
	}

	protected void handleSetProductPrices(ProductPriceVO product)
			throws Exception {
		AccessControl.forceCanAdminPrices();
		if (product.getPrice() <= 0)
			throw new UserInputException("A price can not be zero or negative.");
		if ((product.getNormalDiscount() < 0)
				|| (product.getNormalDiscount() > 100))
			throw new UserInputException("Invalid normal discount.");
		if ((product.getIndustrialDiscount() < 0)
				|| (product.getIndustrialDiscount() > 100))
			throw new UserInputException("Invalid industrial discount.");
		Product p = getProductDao().productPriceVOToEntity(product);
		getProductDao().update(p);
	}

	/**
	 * @see edu.uwlax.cs.oayonlinestore.service.Onlinestore#setUserInactive(int)
	 */
	protected void handleSetUserInactive(int userID) throws java.lang.Exception {

		if (!this.handleGetLoggedInUser().isIsAdministrator())
			throw new AccessDeniedException();

		User u = getUserDao().load(userID);
		u.setIsActive(false);
		getUserDao().update(u);

	}

	protected void handleUpdateOrderEdit(OrderEditVO orderEdit,
			boolean storeCCInProfile) throws Exception {

		if (orderEdit.getCcNumber() == null
				|| orderEdit.getCcNumber().length() == 0)
			throw new UserInputException("Creadit Card Number needed.");

		if (orderEdit.getCcCompany() == null
				|| orderEdit.getCcCompany().length() == 0)
			throw new UserInputException("Creadit Card Institute needed.");

		if (orderEdit.getCcExpirationDate() == null
				|| orderEdit.getCcExpirationDate().before(new Date()))
			throw new UserInputException(
					"Credit Card Exporation Date is invalid.");

		if (orderEdit.getCcNumber().length() != 16)
			throw new UserInputException(
					"The credit card number should be 16 digits !.");

		AccessControl.forceCanEditOrder(getOrderDao().load(orderEdit.getId()));

		Order o = getOrderDao().orderEditVOToEntity(orderEdit);
		getOrderDao().update(o);

		if (storeCCInProfile) {
			User u = o.getUser();
			u.setCcCompany(o.getCcCompany());
			u.setCcExpirationDate(o.getCcExpirationDate());
			u.setCcNumber(o.getCcNumber());
			getUserDao().update(u);
		}
	}

}